/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package domain;
import domain.exceptions.NoSuchSquareException;
import domain.exceptions.CannotPlaceAgentHereException;
import domain.Game.direction;
import domain.exceptions.CannotFlagWallSquareException;
/**
 *
 * @author shaigi
 */
public abstract class Square {
    
    private int     _row;
    private int     _column;
    private Agent   _agent;
    private Flag    _flag;
    
    //private Vector<Observer> _observers = new Vector<Observer>();
        
    @Override
    public abstract String toString();
    public abstract void placeAgent(Agent agent) throws CannotPlaceAgentHereException;
    
    public boolean isAgentHere(){
        return _agent != null;
    }
    
    public Square neighbour(direction d) throws NoSuchSquareException{
        Square res = null;
        try{
            switch (d){
                case UP:    res = Game._board.getSquare(_row-1, _column);   break;
                case DOWN:  res = Game._board.getSquare(_row+1, _column);   break;
                case RIGHT: res = Game._board.getSquare(_row, _column+1);   break;
                case LEFT:  res = Game._board.getSquare(_row, _column-1);   break;
            }
        } catch (IndexOutOfBoundsException e){
            throw new NoSuchSquareException();
        }
        return res;
    }
    
    public void removeAgent() throws Exception {
        if (this._agent == null) {
            throw new Exception("Trying to remove an Agent from an empty square");
        } else {
            this._agent = null;
            //TODO update GUI
        }
    }
    
    public Agent getAgent() {
        return _agent;
    }
    
    public int getRow() {
        return _row;
    }

    public void setRow(int row) {
        this._row = row;
    }

    public int getColumn() {
        return _column;
    }

    public void setColumn(int column) {
        this._column = column;
    }

    public void setAgent(Agent agent) {
        this._agent = agent;
        //TODO update GUI
    }
    
    public String toStringLocation(){
        return "  location: " + _row + "," + _column;
    }

    public boolean isContainFlag() {
        return _flag != null;
    }

    public void setFlag(Flag flag) throws CannotFlagWallSquareException{
        if ( !isContainFlag() ){
            this._flag = flag;
            //TODO update GUI:
            //updateGui();
        }
        else{
            throw new CannotFlagWallSquareException("This square is already flaged");
        }
    }
    
    int getCost() {
        return this._flag.getValue();
    }
    
    public boolean equals(Square other){
        return this._row == other._row  &&
               this._column == other._column;
    }

    public Flag getFlag() {
        return _flag;
    }
    /*
    public void subscribe(Observer observer){
        this._observers.addElement(observer);
    }

    private void updateGui() {
        for (Iterator<Observer> it = _observers.iterator(); it.hasNext();) {
            Observer observer = it.next();
            observer.updateGui(this);
        }
    }
     */
}
